Due to advancements in processing technology, complex integrated circuits (ICs) can be designed at various levels of abstraction. Using a hardware description language (HDL), circuits can be designed at the gate level, the register transfer level (RTL), and higher logical levels. When designing using an HDL, the design is often structured in a modular manner. The designer describes each module as a process describing behavior of a system, the behavior describing the generation and propagation of signals through combinatorial logic from one set of registers to another set of registers. HDLs provide a rich set of constructs to describe the functionality of a module. Modules may be combined and augmented to form even higher-level modules.
Prior to implementation, an HDL-based design can be simulated to determine whether the design will function as required. Wasted manufacturing costs due to faulty design may thereby be avoided. Numerous tools are available for simulating circuit designs including, for example, high-level modeling systems (HLMS) and HDL simulators.
Simulation of an HDL-based design includes a compilation phase and a runtime simulation phase. In the compilation phase, HDL source code is input, analyzed, and elaborated to generate executable simulation code. In the runtime simulation phase, the code generated in the compilation phase is executed by a simulation engine to simulate the design. From a user's perspective, HDL simulators work by compiling the HDL-based design once, and then executing the compiled design many times for different sets of input values during the runtime phase. Therefore, the runtime performance of HDL simulators is of critical importance and may be more important than compile time performance in many cases.
An HDL-based design is a hierarchy of modules whose behavior is described by HDL processes. When the HDL-based design is written in VHDL, an HDL process corresponds to either a VHDL process, a concurrent signal assignment, or a concurrent assertion. When the HDL-based design is written in the Verilog language, an HDL process corresponds to either a Verilog always block, an initial block, an assign statement, or a gate. Procedure calls may or may not be regarded as HDL processes. From a hardware perspective, the HDL processes represent hardware that responds to changes in inputs. For example, a change to an output of one circuit may trigger responses in multiple circuits having inputs coupled to the output.
HDL simulators schedule execution of HDL statements such that global variables or signals input to the HDL statements are properly updated and race conditions between concurrent HDL statements are avoided. Simulation of HDL processes is performed over a number of simulation cycles. Each simulation cycle begins with updates to values of nets. Each net, which may be a VHDL signal or a Verilog net, represents values transmitted on a wire of a circuit design. For ease of reference, VHDL signals and Verilog nets may be referred to as either signals or nets, and such terms are used interchangeably herein. Each update to a net may trigger a number of processes which model how a hardware implementation of the design would respond. Processes dependent on the updated nets are scheduled and executed in a delta cycle.
Depending on the circuit design, a net may be changed or updated by the output of multiple processes. Each process output that may affect the value of a net is referred to as a driver. If a process has several statements that assign values to the same net, only one driver for the net is created per process. The value of the driver is computed from all the values assigned to that net in the process, according to predefined language rules. A net that has at most one driver for each bit is said to be singly-driven. A net that has several drivers on the same set of bits is said to be multiply-driven.
When a net is driven by multiple drivers, a value of the net is determined when nets are updated at runtime using a resolution function. The value computed by the resolution function is referred to as the resolved value, and the resolved value will be assigned as the new value of the net. The process of computing the new value from the driver values of a net is called driver resolution. The resolution function can be standard, defined by the HDL language itself or, for VHDL, can be user defined.
Non-Blocking Assignments (NBAs) allow assignment of a value to a net to be scheduled to be performed, by the simulation kernel, at any point before the next simulation cycle without blocking the procedural flow. In contrast, blocking assignments require the assignment to be completed, by the simulation kernel, before continuing with simulation of other statements of a process. An NBA statement can be used whenever several variable assignments within the same simulation cycle can be made without regard to order or dependence upon each other. For instance, one example of an NBA is given by the statement,                a<=b;where the value of ‘b’ is assigned to ‘a’ but generated code should proceed to the next line before assignment actually finishes. This means that the above statement evaluates and schedules the assignment but it does not block the execution of subsequent statements in that block. This implies a sequence of statements such as:        a<=b;        b<=a;may lead to deterministic swapping of values between ‘a’ and ‘b’. Because the procedural flow should not be blocked for NBAs (i.e., the generated code corresponding to NBAs cannot wait to finish the effects of this construct before proceeding to the next construct), special treatment is required for correct simulation of the deterministic and indeterministic behavior of the HDL specification.        
Some NBAs may be triggered by events, and different types of those NBAs may require different treatment. For instance, some NBAs are triggered by an update to a specific net. These are referred to as net-sensitive NBAs. As one example, the statement                a<=@b c;assigns the value of ‘c’ to ‘a’ (after having scheduled the assignment), in response a change in value of ‘b’. As another example, the statement,        a<=repeat(3) @(posedge(b) c);waits for 3 positive edge transitions on ‘b’, before assigning ‘c’ to ‘a.’        
Some non-blocking assignments may include an argument that delays execution of the statement or delays assignments performed by the statements. For instance, in the set of statements:
initial begin
                d<=#10 1;        e<=#2 0;        f<=#4 1;        endd is scheduled to be assigned 1 at time 10, e is scheduled to be assigned 0 at time 2, and f is scheduled to be assigned 1 at time 4. Due to the different treatment required for simulation of different NBA scenarios, simulation of NBAs can be challenging.        
To add further complexity, HDL languages are capable of defining formals of ports to link together multiple nets. This has the effect of shorting net actuals together. Some previous approaches model each shorted net separately, using a separate memory locations to store driver and net values of the different shorted nets. The nets are configured to be sensitive to each other such that an update of a net value of one of the shorted nets will cause other memory locations of ones of the shorted nets to be updated as well. This separate processing of the nets is inefficient. Further, whole nets are not always shorted together. Rather, individual bits of a net may be shorted together while other bits of the nets are not. This requires previous approaches to update each of the shorted nets in a bitwise manner which can further increase computational complexity.
One or more embodiments may address one or more of the above issues.